﻿using System;
using System.Collections;
using System.Net;
using System.Threading;

namespace GT
{
    public partial class WebClientEx : WebClient
    {
        public CookieContainer Cookies { get; set; }
        public string UserAgent { get; set; }
        public int TimeOut { get; set; }
        public HttpWebResponse Response { get; private set; }

        public WebClientEx()
        {
            TimeOut = Timeout.Infinite;
            UserAgent = @"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
            Cookies = new CookieContainer();
        }

        protected override WebResponse GetWebResponse(WebRequest request)
        {
            try
            {
                Response = base.GetWebResponse(request) as HttpWebResponse;
            }
            catch (WebException)
            {
                Response = null;
            }
            return Response;
        }

        protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
        {
            try
            {
                Response = base.GetWebResponse(request, result) as HttpWebResponse;
            }
            catch (WebException)
            {
                Response = null;
            }
            return Response;
        }

        protected override WebRequest GetWebRequest(Uri address)
        {
            HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;

            if (request.GetType() == typeof(HttpWebRequest))
            {
                request.CookieContainer = Cookies;
                request.UserAgent = UserAgent;
                request.Timeout = Timeout.Infinite;
            }
            return request;
        }
    }

    public partial class AssociativeObject
    {
        public AssociativeObject()
        {
            this.Object = new object();
        }

        public AssociativeObject(object obj)
        {
            this.Object = obj;
        }

        private Hashtable fallback = new Hashtable();
        public object Object { get; private set; }
        public dynamic this[object assoc]
        {
            get
            {
                dynamic ret;
                if (assoc is string)
                {
                    try
                    {
                        ret = this.Object.GetPropertyValue(assoc as string);
                        return ret;
                    }
                    catch
                    {
                        if (fallback.ContainsKey(assoc))
                            ret = fallback[assoc];
                        else
                        {
                            fallback[assoc] = null;
                            ret = fallback[assoc];
                        }

                        return ret;
                    }

                }
                else
                {
                    if (fallback.ContainsKey(assoc))
                        ret = fallback[assoc];
                    else
                    {
                        fallback[assoc] = null;
                        ret = fallback[assoc];
                    }

                    return ret;
                }
            }
        }
    }
}